#include <X11/Xlib.h>
#include <unistd.h>
#include <X11/extensions/record.h>
#include <X11/Xutil.h>
#include <string.h>
#include <iostream>

using namespace std;

typedef struct pos_array {
	int a[100][2];
	int length;
	int index;
} POSA;

Display* display;
Display* display2;
Window root;
POSA poss;

void CallBackEvent(XPointer ptr, XRecordInterceptData* data);
void getCursorPos(int& x, int& y);
void mouseClick(int button);

int main(int argc, char** argv) {
	if (argc == 2) {
		poss.length = argv[1][0] - '0';  
		poss.index = 0;
		display = XOpenDisplay(0);
		display2 = XOpenDisplay(0);
		if (display == 0) {
			fprintf(stderr, "不能打开Display连接\n");
			return 0;
		}
		if (display2 == 0) {
			fprintf(stderr, "不能打开Display连接\n");
			return 0;
		}
		root = DefaultRootWindow(display2);
		XRecordClientSpec clients = XRecordAllClients;
		XRecordRange* range = XRecordAllocRange();
		if (range == 0) {
			fprintf(stderr, "不能关联到XRecordRange\n");
			return 0;
		}
		memset(range, 0x00, sizeof(XRecordRange));
		range->device_events.first = KeyPress;
		range->device_events.last = MotionNotify;

		XRecordContext context = XRecordCreateContext (display, 0, &clients, 1, &range, 1);
		if (context == 0) {
			fprintf(stderr, "创建上下文失败\n");
			return 0;
		}

		XFree(range);

		XSync(display, True);

		cout << "开始监听" << endl;
		XRecordEnableContext(display, context,  CallBackEvent, NULL);
	}
	else {
		fprintf(stderr, "无效的参数\n") ;
	}
}

void CallBackEvent(XPointer ptr, XRecordInterceptData* data) {
	if (data->category == XRecordFromServer) {
		XEvent* e = (XEvent*)data->data;
		//按下F2
		//cout << e->type << endl;
		if (e->type == 17410) {
			cout << "press<F2>" << endl;
			for (int i = 0; i < poss.length; i++) {
				XWarpPointer(display2, None, root, 0, 0, 0, 0, poss.a[i][0], poss.a[i][1]);
				XFlush(display2);
				mouseClick(Button1);
				XFlush(display2);
			}
		}
		//按下F1
		else if (e->type == 17154) {
			cout << "press<F1>" << endl;
			getCursorPos(poss.a[poss.index][0], poss.a[poss.index][1]);
			cout << poss.index + 1 << endl;
			if (poss.index >= 0 && poss.index < poss.length)
				poss.index++;
		}
		else if (e->type == 2306) {
			if (poss.index > 0 && poss.index <= poss.length)
				poss.index--;
			cout << poss.index + 1 << endl;
		}
	}
}

void getCursorPos(int& x, int& y) {
	int tmp; 
	unsigned int tmp2;
	Window fromroot, tmpwin;
	XQueryPointer(display2, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp2);
}

void mouseClick(int button)
{
	//打开显示器
    Display *display = XOpenDisplay(NULL);

    XEvent event;

    if(display == NULL)
    {
        fprintf(stderr, "Cannot initialize the display\n");
        exit(EXIT_FAILURE);
    }

    memset(&event, 0x00, sizeof(event));

    event.type = ButtonPress;
    event.xbutton.button = button;
    event.xbutton.same_screen = True;

    XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);

    event.xbutton.subwindow = event.xbutton.window;

    while(event.xbutton.subwindow)
    {
        event.xbutton.window = event.xbutton.subwindow;

        XQueryPointer(display, event.xbutton.window, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
    }

    if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");

    XFlush(display);

    usleep(100000);

    event.type = ButtonRelease;
    event.xbutton.state = 0x100;

    if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");

    XFlush(display);

    XCloseDisplay(display);
}
